


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html id="htmlId">
<head>
  <title>Coverage Report :: DormancyAdvisor</title>
  <style type="text/css">
    @import "../../.css/coverage.css";
  </style>
</head>

<body>
<div class="header"></div>

<div class="content">
<div class="breadCrumbs">
    [ <a href="../../index.html">all classes</a> ]
    [ <a href="../index.html">at.dormancy.aop</a> ]
</div>

<h1>Coverage Summary for Class: DormancyAdvisor (at.dormancy.aop)</h1>

<table class="coverageStats">

<tr>
  <th class="name">Class</th>
<th class="coverageStat 
">
  Method, %
</th>
<th class="coverageStat 
">
  Line, %
</th>
</tr>
<tr>
  <td class="name">DormancyAdvisor</td>
<td class="coverageStat">
  <span class="percent">
    100%
  </span>
  <span class="absValue">
    (12/ 12)
  </span>
</td>
<td class="coverageStat">
  <span class="percent">
    98.3%
  </span>
  <span class="absValue">
    (57/ 58)
  </span>
</td>
</tr>
  <tr>
    <td class="name">DormancyAdvisor$1</td>
<td class="coverageStat">
  <span class="percent">
    100%
  </span>
  <span class="absValue">
    (2/ 2)
  </span>
</td>
<td class="coverageStat">
  <span class="percent">
    33.3%
  </span>
  <span class="absValue">
    (2/ 6)
  </span>
</td>
  </tr>
  <tr>
    <td class="name">DormancyAdvisor$2</td>
<td class="coverageStat">
  <span class="percent">
    100%
  </span>
  <span class="absValue">
    (2/ 2)
  </span>
</td>
<td class="coverageStat">
  <span class="percent">
    33.3%
  </span>
  <span class="absValue">
    (2/ 6)
  </span>
</td>
  </tr>
  <tr>
    <td class="name">DormancyAdvisor$3</td>
<td class="coverageStat">
  <span class="percent">
    100%
  </span>
  <span class="absValue">
    (2/ 2)
  </span>
</td>
<td class="coverageStat">
  <span class="percent">
    100%
  </span>
  <span class="absValue">
    (2/ 2)
  </span>
</td>
  </tr>
  <tr>
    <td class="name">DormancyAdvisor$3$1</td>
<td class="coverageStat">
  <span class="percent">
    100%
  </span>
  <span class="absValue">
    (2/ 2)
  </span>
</td>
<td class="coverageStat">
  <span class="percent">
    100%
  </span>
  <span class="absValue">
    (2/ 2)
  </span>
</td>
  </tr>
  <tr>
    <td class="name">DormancyAdvisor$Mode</td>
<td class="coverageStat">
  <span class="percent">
    100%
  </span>
  <span class="absValue">
    (2/ 2)
  </span>
</td>
<td class="coverageStat">
  <span class="percent">
    100%
  </span>
  <span class="absValue">
    (4/ 4)
  </span>
</td>
  </tr>
<tr>
  <td class="name"><strong>total</strong></td>
<td class="coverageStat">
  <span class="percent">
    100%
  </span>
  <span class="absValue">
    (22/ 22)
  </span>
</td>
<td class="coverageStat">
  <span class="percent">
    88.5%
  </span>
  <span class="absValue">
    (69/ 78)
  </span>
</td>
</tr>
</table>

<br/>
<br/>


<div class="sourceCode"><i>1</i>&nbsp;/*
<i>2</i>&nbsp; * Copyright 2013 Gregor Schauer
<i>3</i>&nbsp; *
<i>4</i>&nbsp; * Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);
<i>5</i>&nbsp; * you may not use this file except in compliance with the License.
<i>6</i>&nbsp; * You may obtain a copy of the License at
<i>7</i>&nbsp; *
<i>8</i>&nbsp; *      http://www.apache.org/licenses/LICENSE-2.0
<i>9</i>&nbsp; *
<i>10</i>&nbsp; * Unless required by applicable law or agreed to in writing, software
<i>11</i>&nbsp; * distributed under the License is distributed on an &quot;AS IS&quot; BASIS,
<i>12</i>&nbsp; * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<i>13</i>&nbsp; * See the License for the specific language governing permissions and
<i>14</i>&nbsp; * limitations under the License.
<i>15</i>&nbsp; */
<i>16</i>&nbsp;package at.dormancy.aop;
<i>17</i>&nbsp;
<i>18</i>&nbsp;import at.dormancy.Dormancy;
<i>19</i>&nbsp;import at.dormancy.persister.EntityPersister;
<i>20</i>&nbsp;import org.aopalliance.aop.Advice;
<i>21</i>&nbsp;import org.aopalliance.intercept.MethodInterceptor;
<i>22</i>&nbsp;import org.aopalliance.intercept.MethodInvocation;
<i>23</i>&nbsp;import org.apache.commons.lang.StringUtils;
<i>24</i>&nbsp;import org.apache.log4j.Logger;
<i>25</i>&nbsp;import org.aspectj.lang.ProceedingJoinPoint;
<i>26</i>&nbsp;import org.aspectj.lang.annotation.Aspect;
<i>27</i>&nbsp;import org.aspectj.lang.reflect.MethodSignature;
<i>28</i>&nbsp;import org.springframework.aop.MethodMatcher;
<i>29</i>&nbsp;import org.springframework.aop.Pointcut;
<i>30</i>&nbsp;import org.springframework.aop.support.AbstractPointcutAdvisor;
<i>31</i>&nbsp;import org.springframework.aop.support.AopUtils;
<i>32</i>&nbsp;import org.springframework.aop.support.annotation.AnnotationMatchingPointcut;
<i>33</i>&nbsp;import org.springframework.aop.support.annotation.AnnotationMethodMatcher;
<i>34</i>&nbsp;import org.springframework.beans.factory.BeanFactory;
<i>35</i>&nbsp;import org.springframework.beans.factory.BeanFactoryAware;
<i>36</i>&nbsp;import org.springframework.core.Ordered;
<i>37</i>&nbsp;import org.springframework.core.annotation.Order;
<i>38</i>&nbsp;import org.springframework.util.Assert;
<i>39</i>&nbsp;
<i>40</i>&nbsp;import javax.annotation.Nonnull;
<i>41</i>&nbsp;import javax.annotation.Nullable;
<i>42</i>&nbsp;import javax.inject.Inject;
<i>43</i>&nbsp;import java.lang.annotation.Annotation;
<i>44</i>&nbsp;import java.lang.reflect.Method;
<i>45</i>&nbsp;import java.util.Arrays;
<i>46</i>&nbsp;import java.util.concurrent.Callable;
<i>47</i>&nbsp;
<i>48</i>&nbsp;/**
<i>49</i>&nbsp; * Intercepts calls and performs cloning and merging of Hibernate entities.
<i>50</i>&nbsp; * &lt;p/&gt;
<i>51</i>&nbsp; * At first, an {@link EntityPersister} is resolved in the following sequence:
<i>52</i>&nbsp; * &lt;ol&gt;
<i>53</i>&nbsp; * &lt;li&gt;Use the metadata of the {@link PersistenceEndpoint} annotation on the method to invoke&lt;/li&gt;
<i>54</i>&nbsp; * &lt;li&gt;Use the metadata of the {@link PersistenceEndpoint} annotation on the object instance&lt;/li&gt;
<i>55</i>&nbsp; * &lt;/ol&gt;
<i>56</i>&nbsp; * If any {@link PersistenceEndpoint} annotation is present, get an {@link EntityPersister} from the {@link BeanFactory}
<i>57</i>&nbsp; * with the given {@code name}. Otherwise, get an {@link EntityPersister} of the specified {@code type} from
<i>58</i>&nbsp; * {@link Dormancy}. If no appropriate {@link EntityPersister} is registered, {@link Dormancy} will be used.
<i>59</i>&nbsp; *
<i>60</i>&nbsp; * @author Gregor Schauer
<i>61</i>&nbsp; * @see Dormancy
<i>62</i>&nbsp; * @see EntityPersister
<i>63</i>&nbsp; * @see PersistenceEndpoint
<i>64</i>&nbsp; */
<i>65</i>&nbsp;@Aspect
<i>66</i>&nbsp;@Order(Ordered.LOWEST_PRECEDENCE) // make sure this is invoked after other aspects e.g., transaction or validation
<i>67</i>&nbsp;public class DormancyAdvisor extends AbstractPointcutAdvisor implements MethodInterceptor, BeanFactoryAware {
<b class="fc"><i>68</i>&nbsp;	protected static final Logger logger = Logger.getLogger(DormancyAdvisor.class);</b>
<b class="fc"><i>69</i>&nbsp;	protected Class&lt;? extends Annotation&gt; annotationType = PersistenceEndpoint.class;</b>
<i>70</i>&nbsp;	protected Pointcut pointcut;
<i>71</i>&nbsp;	protected Integer order;
<i>72</i>&nbsp;
<b class="fc"><i>73</i>&nbsp;	public enum Mode {</b>
<i>74</i>&nbsp;		/**
<i>75</i>&nbsp;		 * Processes parameters of intercepted methods only.
<i>76</i>&nbsp;		 */
<b class="fc"><i>77</i>&nbsp;		PARAMETERS,</b>
<i>78</i>&nbsp;		/**
<i>79</i>&nbsp;		 * Processes results of intercepted methods only.
<i>80</i>&nbsp;		 */
<b class="fc"><i>81</i>&nbsp;		RESULT,</b>
<i>82</i>&nbsp;		/**
<i>83</i>&nbsp;		 * Processes parameters as well as results of intercepted methods.
<i>84</i>&nbsp;		 */
<b class="fc"><i>85</i>&nbsp;		BOTH</b>
<i>86</i>&nbsp;	}
<i>87</i>&nbsp;
<i>88</i>&nbsp;	protected Dormancy dormancy;
<b class="fc"><i>89</i>&nbsp;	protected Mode mode = Mode.RESULT;</b>
<i>90</i>&nbsp;	protected BeanFactory beanFactory;
<i>91</i>&nbsp;
<i>92</i>&nbsp;	@Inject
<b class="fc"><i>93</i>&nbsp;	public DormancyAdvisor(@Nonnull Dormancy dormancy) {</b>
<b class="fc"><i>94</i>&nbsp;		this.dormancy = dormancy;</b>
<b class="fc"><i>95</i>&nbsp;	}</b>
<i>96</i>&nbsp;
<i>97</i>&nbsp;	@Nullable
<i>98</i>&nbsp;	@SuppressWarnings(&quot;unchecked&quot;)
<i>99</i>&nbsp;	private Object process(@Nonnull Object[] args, @Nonnull Method method, @Nonnull Object target, @Nonnull Callable&lt;?&gt; callable) throws Throwable {
<i>100</i>&nbsp;		// If the method to invoke takes no parameters and does not return anything, directly invoke it
<b class="fc"><i>101</i>&nbsp;		if (args.length == 0 &amp;&amp; method.getReturnType() == void.class) {</b>
<b class="fc"><i>102</i>&nbsp;			return callable.call();</b>
<i>103</i>&nbsp;		}
<i>104</i>&nbsp;
<b class="fc"><i>105</i>&nbsp;		EntityPersister entityPersister = dormancy;</b>
<i>106</i>&nbsp;
<i>107</i>&nbsp;		// Retrieve the persistence endpoint annotation from the method (if present)
<b class="fc"><i>108</i>&nbsp;		Annotation annotation = method.getAnnotation(annotationType);</b>
<b class="fc"><i>109</i>&nbsp;		if (annotation == null) {</b>
<i>110</i>&nbsp;			// Retrieve the annotation from the object instance (if present)
<b class="fc"><i>111</i>&nbsp;			annotation = target.getClass().getAnnotation(annotationType);</b>
<i>112</i>&nbsp;		}
<i>113</i>&nbsp;
<i>114</i>&nbsp;		// If a persistence endpoint annotation was found
<b class="fc"><i>115</i>&nbsp;		if (annotation != null &amp;&amp; annotation.annotationType() == PersistenceEndpoint.class) {</b>
<b class="fc"><i>116</i>&nbsp;			PersistenceEndpoint persistenceEndpoint = PersistenceEndpoint.class.cast(annotation);</b>
<b class="fc"><i>117</i>&nbsp;			String name = persistenceEndpoint.name();</b>
<b class="fc"><i>118</i>&nbsp;			if (!StringUtils.isEmpty(name)) {</b>
<i>119</i>&nbsp;				// If the name attribute is set, retrieve an EntityPersister from the BeanFactory
<b class="fc"><i>120</i>&nbsp;				Assert.notNull(beanFactory, &quot;BeanFactory must not be null&quot;);</b>
<b class="fc"><i>121</i>&nbsp;				entityPersister = beanFactory.getBean(name, EntityPersister.class);</b>
<b class="fc"><i>122</i>&nbsp;			} else if (persistenceEndpoint.types().length &gt; 0) {</b>
<i>123</i>&nbsp;				// If types are set, look for an registered EntityPersister
<b class="fc"><i>124</i>&nbsp;				Class&lt;? extends EntityPersister&gt;[] types = persistenceEndpoint.types();</b>
<b class="fc"><i>125</i>&nbsp;				for (Class&lt;? extends EntityPersister&gt; clazz : types) {</b>
<b class="fc"><i>126</i>&nbsp;					entityPersister = dormancy.getEntityPersister(clazz);</b>
<b class="fc"><i>127</i>&nbsp;					if (entityPersister != null) {</b>
<b class="fc"><i>128</i>&nbsp;						break;</b>
<i>129</i>&nbsp;					}
<i>130</i>&nbsp;				}
<b class="fc"><i>131</i>&nbsp;				if (entityPersister == null) {</b>
<b class="fc"><i>132</i>&nbsp;					throw new IllegalArgumentException(&quot;No EntityPersister registered for any of the types: &quot; + Arrays.toString(types));</b>
<i>133</i>&nbsp;				}
<i>134</i>&nbsp;			}
<i>135</i>&nbsp;		}
<i>136</i>&nbsp;
<i>137</i>&nbsp;		// Process method parameters (if enabled)
<b class="fc"><i>138</i>&nbsp;		if (mode == Mode.PARAMETERS || mode == Mode.BOTH) {</b>
<b class="fc"><i>139</i>&nbsp;			if (logger.isDebugEnabled()) {</b>
<b class="fc"><i>140</i>&nbsp;				logger.debug(String.format(&quot;Using %s for method invocation %s.%s(%s)&quot;,</b>
<i>141</i>&nbsp;						entityPersister.getClass().getSimpleName(), target.getClass().getName(),
<i>142</i>&nbsp;						method.getName(), Arrays.toString(args)));
<i>143</i>&nbsp;			}
<b class="fc"><i>144</i>&nbsp;			for (int i = 0; i &lt; args.length; i++) {</b>
<b class="fc"><i>145</i>&nbsp;				args[i] = entityPersister.merge(args[i]);</b>
<i>146</i>&nbsp;			}
<i>147</i>&nbsp;		}
<i>148</i>&nbsp;
<i>149</i>&nbsp;		// Invoke the desired method
<b class="fc"><i>150</i>&nbsp;		Object result = callable.call();</b>
<i>151</i>&nbsp;
<i>152</i>&nbsp;		// Process the result (if enabled)
<b class="fc"><i>153</i>&nbsp;		if (mode == Mode.RESULT || mode == Mode.BOTH) {</b>
<b class="fc"><i>154</i>&nbsp;			if (logger.isDebugEnabled()) {</b>
<b class="fc"><i>155</i>&nbsp;				logger.debug(String.format(&quot;Using %s for method result %s.%s(%s) =&gt; %s&quot;,</b>
<i>156</i>&nbsp;						entityPersister.getClass().getSimpleName(), target.getClass().getName(),
<i>157</i>&nbsp;						method.getName(), Arrays.toString(args), result));
<i>158</i>&nbsp;			}
<b class="fc"><i>159</i>&nbsp;			result = result != null ? entityPersister.clone(result) : result;</b>
<i>160</i>&nbsp;		}
<b class="fc"><i>161</i>&nbsp;		return result;</b>
<i>162</i>&nbsp;	}
<i>163</i>&nbsp;
<i>164</i>&nbsp;	@Nullable
<i>165</i>&nbsp;	public Object around(@Nonnull final ProceedingJoinPoint joinPoint) throws Throwable {
<b class="fc"><i>166</i>&nbsp;		Method method = MethodSignature.class.cast(joinPoint.getSignature()).getMethod();</b>
<b class="fc"><i>167</i>&nbsp;		return process(joinPoint.getArgs(), method, joinPoint.getTarget(), new Callable&lt;Object&gt;() {</b>
<i>168</i>&nbsp;			@Override
<i>169</i>&nbsp;			public Object call() throws Exception {
<i>170</i>&nbsp;				try {
<b class="fc"><i>171</i>&nbsp;					return joinPoint.proceed();</b>
<b class="nc"><i>172</i>&nbsp;				} catch (Exception e) {</b>
<b class="nc"><i>173</i>&nbsp;					throw e;</b>
<b class="nc"><i>174</i>&nbsp;				} catch (Throwable throwable) {</b>
<b class="nc"><i>175</i>&nbsp;					throw new RuntimeException(throwable);</b>
<i>176</i>&nbsp;				}
<i>177</i>&nbsp;			}
<i>178</i>&nbsp;		});
<i>179</i>&nbsp;	}
<i>180</i>&nbsp;
<i>181</i>&nbsp;	@Nullable
<i>182</i>&nbsp;	@Override
<i>183</i>&nbsp;	public Object invoke(@Nonnull final MethodInvocation invocation) throws Throwable {
<b class="fc"><i>184</i>&nbsp;		return process(invocation.getArguments(), invocation.getMethod(), invocation.getThis(), new Callable&lt;Object&gt;() {</b>
<i>185</i>&nbsp;			@Override
<i>186</i>&nbsp;			public Object call() throws Exception {
<i>187</i>&nbsp;				try {
<b class="fc"><i>188</i>&nbsp;					return invocation.proceed();</b>
<b class="nc"><i>189</i>&nbsp;				} catch (Exception e) {</b>
<b class="nc"><i>190</i>&nbsp;					throw e;</b>
<b class="nc"><i>191</i>&nbsp;				} catch (Throwable throwable) {</b>
<b class="nc"><i>192</i>&nbsp;					throw new RuntimeException(throwable);</b>
<i>193</i>&nbsp;				}
<i>194</i>&nbsp;			}
<i>195</i>&nbsp;		});
<i>196</i>&nbsp;	}
<i>197</i>&nbsp;
<i>198</i>&nbsp;	@Nonnull
<i>199</i>&nbsp;	@Override
<i>200</i>&nbsp;	public Pointcut getPointcut() {
<b class="fc"><i>201</i>&nbsp;		if (pointcut == null) {</b>
<b class="fc"><i>202</i>&nbsp;			pointcut = new AnnotationMatchingPointcut(null, annotationType) {</b>
<i>203</i>&nbsp;				@Nonnull
<i>204</i>&nbsp;				@Override
<i>205</i>&nbsp;				public MethodMatcher getMethodMatcher() {
<b class="fc"><i>206</i>&nbsp;					return new AnnotationMethodMatcher(annotationType) {</b>
<i>207</i>&nbsp;						@Override
<i>208</i>&nbsp;						public boolean matches(Method method, Class targetClass) {
<b class="fc"><i>209</i>&nbsp;							return super.matches(method, targetClass)</b>
<i>210</i>&nbsp;									|| AopUtils.getTargetClass(targetClass).isAnnotationPresent(annotationType);
<i>211</i>&nbsp;						}
<i>212</i>&nbsp;					};
<i>213</i>&nbsp;				}
<i>214</i>&nbsp;			};
<i>215</i>&nbsp;		}
<b class="fc"><i>216</i>&nbsp;		return pointcut;</b>
<i>217</i>&nbsp;	}
<i>218</i>&nbsp;
<i>219</i>&nbsp;	@Nonnull
<i>220</i>&nbsp;	@Override
<i>221</i>&nbsp;	public Advice getAdvice() {
<b class="fc"><i>222</i>&nbsp;		return this;</b>
<i>223</i>&nbsp;	}
<i>224</i>&nbsp;
<i>225</i>&nbsp;	@Override
<i>226</i>&nbsp;	public int getOrder() {
<b class="fc"><i>227</i>&nbsp;		if (order != null) {</b>
<b class="fc"><i>228</i>&nbsp;			return order;</b>
<i>229</i>&nbsp;		}
<b class="fc"><i>230</i>&nbsp;		Advice advice = getAdvice();</b>
<b class="fc"><i>231</i>&nbsp;		if (advice instanceof Ordered &amp;&amp; advice != this) {</b>
<b class="nc"><i>232</i>&nbsp;			return ((Ordered) advice).getOrder();</b>
<i>233</i>&nbsp;		}
<b class="fc"><i>234</i>&nbsp;		return Ordered.LOWEST_PRECEDENCE;</b>
<i>235</i>&nbsp;	}
<i>236</i>&nbsp;
<i>237</i>&nbsp;	@Override
<i>238</i>&nbsp;	public void setOrder(int order) {
<b class="fc"><i>239</i>&nbsp;		this.order = order;</b>
<b class="fc"><i>240</i>&nbsp;	}</b>
<i>241</i>&nbsp;
<i>242</i>&nbsp;	@Override
<i>243</i>&nbsp;	public void setBeanFactory(@Nonnull BeanFactory beanFactory) {
<b class="fc"><i>244</i>&nbsp;		this.beanFactory = beanFactory;</b>
<b class="fc"><i>245</i>&nbsp;	}</b>
<i>246</i>&nbsp;
<i>247</i>&nbsp;	/**
<i>248</i>&nbsp;	 * Sets the Mode that should be used to process method parameters and return values, respectively.
<i>249</i>&nbsp;	 *
<i>250</i>&nbsp;	 * @param mode the mode to operate
<i>251</i>&nbsp;	 */
<i>252</i>&nbsp;	public void setMode(@Nonnull Mode mode) {
<b class="fc"><i>253</i>&nbsp;		this.mode = mode;</b>
<b class="fc"><i>254</i>&nbsp;	}</b>
<i>255</i>&nbsp;
<i>256</i>&nbsp;	/**
<i>257</i>&nbsp;	 * Sets the annotation type that indicates a persistence endpoint.
<i>258</i>&nbsp;	 *
<i>259</i>&nbsp;	 * @param annotationType the type of the annotation
<i>260</i>&nbsp;	 */
<i>261</i>&nbsp;	public void setAnnotationType(@Nonnull Class&lt;? extends Annotation&gt; annotationType) {
<b class="fc"><i>262</i>&nbsp;		this.annotationType = annotationType;</b>
<b class="fc"><i>263</i>&nbsp;	}</b>
<i>264</i>&nbsp;}
</div>
</div>

<div class="footer">
    
    <div style="float:right;">generated on 2013-07-31 23:31</div>
</div>
</body>
</html>
